package com.oliver.picturebackendcommon.manager;


import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * @ClassName CacheManager
 * @Description 缓存操作类
 * @Author snow
 * @Date 2024/12/17 20:24
 **/

@Component
public class CacheManager {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * guava本地缓存
     */
    private final Cache<String,Object> LOCAL_CACHE=
            Caffeine.newBuilder()
                    .maximumSize(1000L)
                    //  缓存5分钟后消失
                    .expireAfterWrite(5L, TimeUnit.MINUTES)
                    .build();


    /**
     * 获取多级缓存的方法
     * @param clazz
     * @param key
     * @return
     * @param <T>
     */
    public <T> T getStrCache(Class<T> clazz, String key){
        String localCacheValue = (String) LOCAL_CACHE.getIfPresent(key);
        if (StrUtil.isNotBlank(localCacheValue)){
            T cachedObj = JSONUtil.toBean(localCacheValue, clazz);
            return cachedObj;
        }

        String redisCacheValue = stringRedisTemplate.opsForValue().get(key);
        if (StrUtil.isNotBlank(redisCacheValue)){
            T cachedObj = JSONUtil.toBean(redisCacheValue, clazz);
            return cachedObj;
        }

        return null;
    }

    public void setStrCache(String key,Object value,int expireTime){
        //  设置本地缓存
        LOCAL_CACHE.put(key, value);
        //  设置redis缓存
        stringRedisTemplate.opsForValue().set(key,(String) value,expireTime,TimeUnit.SECONDS);
    }

    /**
     * 删除首页缓存
     */
    public void deleteHomeStrCache(){
        //  首页缓存键前缀
        String cacheKeyPrefix = "oliverpicture:listPictureVOByPageOnHome:";

        // 删除 Redis 中首页的缓存键
        stringRedisTemplate.execute((RedisConnection connection) -> {
            ScanOptions options = ScanOptions.scanOptions().match(cacheKeyPrefix +"*").build();
            Cursor<byte[]> cursor = connection.scan(options);
            while (cursor.hasNext()) {
                connection.del(cursor.next());
            }
            return null;
        });

        //  删除本地缓存
        LOCAL_CACHE.asMap().keySet()
                .forEach(key -> {
                    if (key.startsWith(cacheKeyPrefix)){
                        LOCAL_CACHE.invalidate(key);
                    }
                });
    }

}
